package com.mark.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mark.entity.Order;
import com.mark.entity.Order2;
import com.mark.mapper.Order2Mapper;
import com.mark.mapper.OrderMapper;
import com.mark.service.OrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * @author: yangguoxiong
 * @date: 2023/11/19 20:42
 * @description:
 */
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private Order2Mapper order2Mapper;

    @Autowired
    private DataSource dataSource;

    @Override
    @Transactional
    public Order transactionalInsertAndQuery() {
        // 测试，在一个事务中，我不插入，先查询，会查主库还是从库？答：是先查从库。
        Order getById = this.getById(1L);
        log.info("先查询的结果：{}", getById);

        Order order = new Order();
        order.setOrderId(IdWorker.getId());
        order.setName("订单666");
        order.setUserId(1L);
        order.setStatus(1);
        this.save(order);
        log.info("插入结果：{}", order);
        // 测试，在一个事务中，当我插入又后去查询时，会查主库还是从库？答：会用主库去查询，为了确保事务一致性。
        Order byId = this.getById(order.getOrderId());
        log.info("查询结果：{}", byId);

        // 测试，在一个事务中，当我插入后查询的不是插入的这条数据，会查主库还是从库？答：会查主库，因为发生了增删改操作，所以插入后面的查询都是用主库了。
        Order byId1 = this.getById(1L);
        log.info("查询结果：{}", byId1);

        // 测试，在一个事务中，当我插入后查询另外一张表的数据，会查主库还是从库？答：会查主库，因为发生了增删改操作，所以插入后面的查询都是用主库了。
        Order2 order2 = order2Mapper.selectById(1L);
        log.info("查询结果：{}", order2);
        return byId;
    }

    @Override
    @SneakyThrows
    @Transactional
    public Order testTransactionSingleQuery() {
        Connection connection = dataSource.getConnection();
        log.info("连接信息是ShardingConnection，数据源信息是ShardingDataSource：{}", connection);
        // 测试，在一个事务中，当只有查询时，sharding-jdbc是会使用从库去查询。
        Order byId = this.getById(1726227358229946370L);
        log.info("查询结果：{}", byId);
        return byId;
    }

    @Override
    public Order normalQuery() {
        // 测试，在没有事务时，当只有查询时，sharding-jdbc是会使用从库去查询。
        Order byId = this.getById(1726227358229946370L);
        log.info("查询结果：{}", byId);
        return byId;
    }
}
